package ua.khpi.si.kit49.diploma.service;

import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.List;

import org.apache.log4j.Logger;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

import ua.khpi.si.kit49.diploma.core.Constants;
import ua.khpi.si.kit49.diploma.db.dao.CityDAO;
import ua.khpi.si.kit49.diploma.db.dto.City;
import ua.khpi.si.kit49.diploma.exception.WeatherException;

/**
 * Implementation of city service
 * 
 * @author netstalk3r
 * 
 */

@Service("cityService")
public class CityServiceImpl implements CityService {

	private static final Logger log = Logger.getLogger(CityServiceImpl.class);

	@Autowired(required = true)
	private CityDAO cityDAO;

	@Autowired(required = true)
	private WeatherService weatherService;

	@Transactional(propagation = Propagation.REQUIRED, readOnly = true)
	public List<City> getAllCities() throws Exception {
		log.info("getAllCities");
		CityHolder cityHolder = CityHolder.getInstance();
		try {
			log.info("Is list with cities empty - " + cityHolder.isListEmpty());
			if (cityHolder.isListEmpty()) {
				cityHolder.setListOfCities(cityDAO.getAllCities());
			}
			Date lastUpdateDate = cityHolder.getLastUpdateDate();
			SimpleDateFormat dateFormatter = new SimpleDateFormat(
					Constants.DATE_FORMAT);
			String dateString = dateFormatter.format(new Date());
			Date currentDate = dateFormatter.parse(dateString);
			log.info("Last update date - " + lastUpdateDate
					+ "; Current date - " + currentDate);
			if (lastUpdateDate == null || !lastUpdateDate.equals(currentDate)) {
				cityHolder.setListOfCities(weatherService
						.getWeatherForAllCities(cityHolder.getListOfCities()));
				cityHolder.setLastUpdateDate(currentDate);
			}
		} catch (ParseException e) {
			log.error("Parse Date Exception");
			throw new Exception("company.error.parse.error");
		} catch (WeatherException e) {
			throw new Exception(e.getMessage());
		} catch (Exception e) {
			log.error(e.getMessage());
			throw new Exception(e.getMessage());
		}
		return cityHolder.getListOfCities();
	}

	@Override
	@Transactional(propagation = Propagation.REQUIRED, readOnly = true)
	public City getCityById(Integer id) throws Exception {
		CityHolder cityHolder = CityHolder.getInstance();
		log.info(cityHolder.isListEmpty());
		try {
			if (cityHolder.isListEmpty()) {
				cityHolder.setListOfCities(cityDAO.getAllCities());
				Date lastUpdateDate = cityHolder.getLastUpdateDate();
				SimpleDateFormat dateFormatter = new SimpleDateFormat(
						Constants.DATE_FORMAT);
				String dateString = dateFormatter.format(new Date());
				Date currentDate = dateFormatter.parse(dateString);
				log.info("Last update date - " + lastUpdateDate
						+ "; Current date - " + currentDate);
				if (lastUpdateDate == null
						|| !lastUpdateDate.equals(currentDate)) {
					cityHolder.setListOfCities(weatherService
							.getWeatherForAllCities(cityHolder
									.getListOfCities()));
					cityHolder.setLastUpdateDate(currentDate);
				}
			}
		} catch (WeatherException e) {
			throw new Exception(e.getMessage());
		}
		return cityHolder.getCityById(id);
	}

	@Override
	@Transactional(propagation = Propagation.REQUIRED, readOnly = true)
	public Integer getAmountOfCity() {
		return cityDAO.getAmountOfCity();
	}

}
